// CompressDialog.h

#ifndef __COMPRESS_DIALOG_H
#define __COMPRESS_DIALOG_H

#include "Common/Archive/LoadCodecs.h"
#include "Common/App/AppRegistry.h"

#include "CompressDialogRes.h"

#include <vector>

namespace CompressDialog
{
  namespace UpdateMode
  {
	  //this enum duplicates UpdateArchive
    enum EEnum
    {
      kAdd,
      kUpdate,
      kFresh,
      kSynchronize
    };
  }
  struct CInfo
  {
    UpdateMode::EEnum UpdateMode;
    bool SolidIsSpecified;
    bool MultiThreadIsAllowed;
    UINT64 SolidBlockSize;
    UINT32 NumThreads;

	std::vector<UINT64> VolumeSizes;

    UINT32 Level;
    CString Method;
    UINT32 Dictionary;
    bool OrderMode;
    UINT32 Order;
    CString Options;

    CString EncryptionMethod;

    bool SFXMode;
    bool OpenShareForWrite;

    
    CString ArchiveName; // in: Relative for ; out: abs
    CString CurrentDirPrefix;
    bool KeepName;

    bool GetFullPathName(CString &result) const;

    int FormatIndex;

    CString Password;
    bool EncryptHeadersIsAllowed;
    bool EncryptHeaders;

    void Init()
    {
      Level = Dictionary = Order = UINT32(-1);
      OrderMode = false;
      Method.Empty();
      Options.Empty();
      EncryptionMethod.Empty();
    }
    CInfo()
    {
      Init();
    }
  };
}

class CCompressDialog: public CDialogImpl<CCompressDialog>

//NWindows::NControl::CModalDialog
{
  CComboBox m_ArchivePath;
  CComboBox m_Format;
  CComboBox m_Level;
  CComboBox m_Method;
  CComboBox m_Dictionary;
  CComboBox m_Order;
  CComboBox m_Solid;
  CComboBox m_NumThreads;
  CComboBox m_UpdateMode;
  CComboBox m_Volume;
  //CDialogChildControl m_Params;
	CWindow m_Params;

  CEdit _password1Control;
  CEdit _password2Control;
  CComboBox _encryptionMethod;

  Common::Archive::Compression::CInfo m_RegistryInfo;

  int m_PrevFormat;
  void SetArchiveName(const CString &name);
  size_t FindRegistryFormat(const CString &name);
  size_t FindRegistryFormatAlways(const CString &name);
  
  void CheckSFXNameChange();
  void SetArchiveName2(bool prevWasSFX);
  
  int GetStaticFormatIndex();

  void SetNearestSelectComboBox(CComboBox &comboBox, UINT32 value);

  void SetLevel();
  
  void SetMethod(int keepMethodId = -1);
  int GetMethodID();
  CString GetMethodSpec();
  CString GetEncryptionMethodSpec();

  bool IsZipFormat();

  void SetEncryptionMethod();

  int AddDictionarySize(UINT32 size, bool kilo, bool maga);
  int AddDictionarySize(UINT32 size);
  
  void SetDictionary();

  UINT32 GetComboValue(CComboBox &c, int defMax = 0);

  UINT32 GetLevel()  { return GetComboValue(m_Level); }
  UINT32 GetLevelSpec()  { return GetComboValue(m_Level, 1); }
  UINT32 GetLevel2();
  UINT32 GetDictionary() { return GetComboValue(m_Dictionary); }
  UINT32 GetDictionarySpec() { return GetComboValue(m_Dictionary, 1); }
  UINT32 GetOrder() { return GetComboValue(m_Order); }
  UINT32 GetOrderSpec() { return GetComboValue(m_Order, 1); }
  UINT32 GetNumThreadsSpec() { return GetComboValue(m_NumThreads, 1); }
  UINT32 GetNumThreads2() { UINT32 num = GetNumThreadsSpec(); if (num == UINT32(-1)) num = 1; return num; }
  UINT32 GetBlockSizeSpec() { return GetComboValue(m_Solid, 1); }

  int AddOrder(UINT32 size);
  void SetOrder();
  bool GetOrderMode();

  void SetSolidBlockSize();
  void SetNumThreads();

  UINT64 GetMemoryUsage(UINT32 dictionary, UINT64 &decompressMemory);
  UINT64 GetMemoryUsage(UINT64 &decompressMemory);
  void PrintMemUsage(UINT res, UINT64 value);
  void SetMemoryUsage();
  void SetParams();
  void SaveOptionsInMem();

  void UpdatePasswordControl();
  bool IsShowPasswordChecked() const
   // { return IsButtonChecked(IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED; }
	  { return IsDlgButtonChecked(IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED; }

  int GetFormatIndex();
public:
		enum { IDD = IDD_DIALOG_COMPRESS};
  
		Common::Archive::CCodecs::ArrayArcInfoEx *ArcFormats;
  std::vector<int> ArcIndices;

  CompressDialog::CInfo Info;
  CString OriginalFileName; // for bzip2, gzip2

	BEGIN_MSG_MAP(CCompressDialog)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_HELP, OnHelp)
		COMMAND_CODE_HANDLER(CBN_SELCHANGE, OnSelectionChange)
		COMMAND_ID_HANDLER(IDOK, OnOK)
		COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
		COMMAND_ID_HANDLER(IDC_COMPRESS_BUTTON_SET_ARCHIVE, OnButtonSetArchive)
		COMMAND_ID_HANDLER(IDC_COMPRESS_SFX, OnButtonSFX)
		COMMAND_ID_HANDLER(IDC_COMPRESS_CHECK_SHOW_PASSWORD, UpdatePasswordControl)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnHelp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnSelectionChange(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
	LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
	LRESULT OnButtonSetArchive(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		OnButtonSetArchive();
		return 0;
	}
	LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		EndDialog(wID);
		return 0;
	}

	LRESULT OnButtonSFX(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		OnButtonSFX();
		SetMemoryUsage();
		return 0;
	}

	LRESULT UpdatePasswordControl(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		UpdatePasswordControl();
		return 0;
	}

  

protected:

  void CheckSFXControlsEnable();
  void CheckVolumeEnable();
  void CheckControlsEnable();

  void OnButtonSetArchive();
  bool IsSFX();
  void OnButtonSFX();

};

#endif
